/**
 * 
 */
package sap.provider;

import com.sap.mw.jco.JCO;

import sap.Connection;
import data.PSPElement;
import data.ReturnValue;

/**
 * @author sebastian
 */
interface Methods {
	public final static String CREATE_METHOD = "Create";
	public final static String UPDATE_METHOD = "Update";
	public final static String DELETE_METHOD = "Delete";
}

/**
 * @author sebastian
 *
 */
public final class PSP implements Methods {
	private static final String UNCHANGEABLE_FIELDS[]
		= { /*"CO_AREA",*/ "NETWORK_ASSIGNMENT", "CURRENCY", "CURRENCY_ISO",
			"FUNC_AREA", "FUNC_AREA_LONG" };
	
	public static PSPElement get(String project, String pspElement) {
		// TODO find exceptions
		Connection con = Connection.getInstance();
		
		JCO.Function function = con.getFunction("BAPI_PROJECT_GETINFO");
		
		// fill import parameter
		// TODO test if we need the following line
		//function.getImportParameterList().setValue(project, "PROJECT_DEFINITION");
		JCO.Table t = function.getTableParameterList().getTable("I_WBS_ELEMENT_TABLE");
		t.appendRow();
		t.setValue(pspElement, "WBS_ELEMENT");
		//t.setValue(project, "PROJECT_DEFINITION");
		
		con.execute(function);
		
		ReturnValue r = Return.getFromStructure(function.
				getExportParameterList().getStructure("RETURN"));
		ReturnValue[] detail = Return.getFromTable(function.
				getTableParameterList().getTable("E_MESSAGE_TABLE"));
		Return.testReturnValue(r, detail);
		
		return classFromStruct(function.getTableParameterList().getTable("E_WBS_ELEMENT_TABLE"));
	}
	
	public static void create(PSPElement psp) {
		maintain(psp, CREATE_METHOD);
	}
	
	public static void maintain(PSPElement psp) {
		maintain(psp, UPDATE_METHOD);
	}
	
	public static void delete(String project, String pspElement) {
		PSPElement psp = new PSPElement();
		psp.wbs_element = pspElement;
		psp.project_definition = project;
		
		delete(psp);
	}
	
	public static void delete(PSPElement psp) {
		maintain(psp, DELETE_METHOD);
	}
	
	private static void maintain(PSPElement psp, String method) {
		// TODO find exceptions
		Connection con = Connection.getInstance();
		
		JCO.Function function = con.getFunction("BAPI_PROJECT_MAINTAIN");
		
		// fill import parameter
		JCO.Structure project = function.getImportParameterList().getStructure("I_PROJECT_DEFINITION");
		project.setValue(psp.project_definition, "PROJECT_DEFINITION");
		JCO.ParameterList tables = function.getTableParameterList();
		JCO.Table t = tables.getTable("I_METHOD_PROJECT");
		t.appendRow();
		t.setValue("WBS-Element", "OBJECTTYPE");
		t.setValue(method, "METHOD");
		t.setValue(psp.wbs_element, "OBJECTKEY");
		t.setValue(1, "REFNUMBER");
		t.appendRow();
		t.setValue("Save", "METHOD");
		t = tables.getTable("I_WBS_ELEMENT_TABLE");
		t.appendRow();
		structFromClass(psp, t);
		if (method.equals(UPDATE_METHOD)) {
			t = tables.getTable("I_WBS_ELEMENT_TABLE_UPDATE");
			t.appendRow();
			Connection.fillX(t, 2);
			for (int i=0; i<UNCHANGEABLE_FIELDS.length; i++)
				t.setValue("", UNCHANGEABLE_FIELDS[i]);
		}
		
		con.execute(function);

		ReturnValue r = Return.getFromStructure(function.
				getExportParameterList().getStructure("RETURN"));
		ReturnValue[] detail = Return.getFromTable(function.
				getTableParameterList().getTable("E_MESSAGE_TABLE"));
		Return.testReturnValue(r, detail);
	}
	
	private static PSPElement classFromStruct(JCO.Record struct) {
		PSPElement result = new PSPElement();
		
		result.wbs_element = struct.getString(0);
		result.project_definition = struct.getString(1);
		result.description = struct.getString(2);
		result.short_id = struct.getString(3);
		result.responsible_no = struct.getString(4);
		result.applicant_no = struct.getString(5);
		result.comp_code = struct.getString(6);
		result.bus_area = struct.getString(7);
		result.co_area = struct.getString(8);
		result.profit_ctr = struct.getString(9);
		result.proj_type = struct.getString(10);
		result.network_assignment = struct.getString(11);
		result.costing_sheet = struct.getString(12);
		result.overhead_key = struct.getString(13);
		result.calendar = struct.getString(14);
		result.priority = struct.getString(15);
		result.equipment = struct.getString(16);
		result.functional_location = struct.getString(17);
		result.currency = struct.getString(18);
		result.currency_iso = struct.getString(19);
		result.plant = struct.getString(20);
		result.user_field_key = struct.getString(21);
		result.user_field_char20_1 = struct.getString(22);
		result.user_field_char20_2 = struct.getString(23);
		result.user_field_char10_1 = struct.getString(24);
		result.user_field_char10_2 = struct.getString(25);
		result.user_field_quan1 = struct.getString(26);
		result.user_field_unit1 = struct.getString(27);
		result.user_field_unit1_iso = struct.getString(28);
		result.user_field_quan2 = struct.getString(29);
		result.user_field_unit2 = struct.getString(30);
		result.user_field_unit2_iso = struct.getString(31);
		result.user_field_curr1 = struct.getString(32);
		result.user_field_cuky1 = struct.getString(33);
		result.user_field_cuky1_iso = struct.getString(34);
		result.user_field_curr2 = struct.getString(35);
		result.user_field_cuky2 = struct.getString(36);
		result.user_field_cuky2_iso = struct.getString(37);
		result.user_field_date1 = struct.getString(38);
		result.user_field_date2 = struct.getString(39);
		result.user_field_flag1 = struct.getString(40);
		result.user_field_flag2 = struct.getString(41);
		result.objectclass = struct.getString(42);
		result.statistical = struct.getString(43);
		result.taxjurcode = struct.getString(44);
		result.int_profile = struct.getString(45);
		result.joint_venture = struct.getString(46);
		result.recovery_ind = struct.getString(47);
		result.equity_type = struct.getString(48);
		result.jv_object_type = struct.getString(49);
		result.jv_jib_class = struct.getString(50);
		result.jv_jib_sub_class_a = struct.getString(51);
		result.deletion_flag = struct.getString(52);
		result.objectclass_ext = struct.getString(53);
		result.wbs_planning_element = struct.getString(54);
		result.wbs_account_assignment_element = struct.getString(55);
		result.wbs_billing_element = struct.getString(56);
		result.respsbl_cctr = struct.getString(57);
		result.respsbl_cctr_controlling_area = struct.getString(58);
		result.request_cctr = struct.getString(59);
		result.request_comp_code = struct.getString(60);
		result.request_cctr_controlling_area = struct.getString(61);
		result.location = struct.getString(62);
		result.change_no = struct.getString(63);
		result.invest_profile = struct.getString(64);
		result.res_anal_key = struct.getString(65);
		result.wbs_cctr_posted_actual = struct.getString(66);
		result.wbs_basic_start_date = struct.getString(67);
		result.wbs_basic_finish_date = struct.getString(68);
		result.wbs_forecast_start_date = struct.getString(69);
		result.wbs_forecast_finish_date = struct.getString(70);
		result.wbs_actual_start_date = struct.getString(71);
		result.wbs_actual_finish_date = struct.getString(72);
		result.wbs_basic_duration = struct.getString(73);
		result.wbs_basic_dur_unit = struct.getString(74);
		result.wbs_basic_dur_unit_iso = struct.getString(75);
		result.wbs_forecast_duration = struct.getString(76);
		result.wbs_forcast_dur_unit = struct.getString(77);
		result.wbs_forecast_dur_unit_iso = struct.getString(78);
		result.wbs_actual_duration = struct.getString(79);
		result.wbs_actual_dur_unit = struct.getString(80);
		result.wbs_actual_dur_unit_iso = struct.getString(81);
		result.wbs_scd_basic_start_date = struct.getString(82);
		result.wbs_scd_basic_finish_date = struct.getString(83);
		result.wbs_scd_forecast_start_date = struct.getString(84);
		result.wbs_scd_forecast_finish_date = struct.getString(85);
		result.wbs_scd_actual_start_date = struct.getString(86);
		result.wbs_scd_actual_finish_date = struct.getString(87);
		result.func_area = struct.getString(88);
		result.func_area_long = struct.getString(89);

		return result;
	}
	
	private static void structFromClass(PSPElement psp, JCO.Record struct) {
		struct.setValue(psp.wbs_element, 0);
		struct.setValue(psp.project_definition, 1);
		struct.setValue(psp.description, 2);
		struct.setValue(psp.short_id, 3);
		struct.setValue(psp.responsible_no, 4);
		struct.setValue(psp.applicant_no, 5);
		struct.setValue(psp.comp_code, 6);
		struct.setValue(psp.bus_area, 7);
		struct.setValue(psp.co_area, 8);
		struct.setValue(psp.profit_ctr, 9);
		struct.setValue(psp.proj_type, 10);
		struct.setValue(psp.network_assignment, 11);
		struct.setValue(psp.costing_sheet, 12);
		struct.setValue(psp.overhead_key, 13);
		struct.setValue(psp.calendar, 14);
		struct.setValue(psp.priority, 15);
		struct.setValue(psp.equipment, 16);
		struct.setValue(psp.functional_location, 17);
		struct.setValue(psp.currency, 18);
		struct.setValue(psp.currency_iso, 19);
		struct.setValue(psp.plant, 20);
		struct.setValue(psp.user_field_key, 21);
		struct.setValue(psp.user_field_char20_1, 22);
		struct.setValue(psp.user_field_char20_2, 23);
		struct.setValue(psp.user_field_char10_1, 24);
		struct.setValue(psp.user_field_char10_2, 25);
		struct.setValue(psp.user_field_quan1, 26);
		struct.setValue(psp.user_field_unit1, 27);
		struct.setValue(psp.user_field_unit1_iso, 28);
		struct.setValue(psp.user_field_quan2, 29);
		struct.setValue(psp.user_field_unit2, 30);
		struct.setValue(psp.user_field_unit2_iso, 31);
		struct.setValue(psp.user_field_curr1, 32);
		struct.setValue(psp.user_field_cuky1, 33);
		struct.setValue(psp.user_field_cuky1_iso, 34);
		struct.setValue(psp.user_field_curr2, 35);
		struct.setValue(psp.user_field_cuky2, 36);
		struct.setValue(psp.user_field_cuky2_iso, 37);
		struct.setValue(psp.user_field_date1, 38);
		struct.setValue(psp.user_field_date2, 39);
		struct.setValue(psp.user_field_flag1, 40);
		struct.setValue(psp.user_field_flag2, 41);
		struct.setValue(psp.objectclass, 42);
		struct.setValue(psp.statistical, 43);
		struct.setValue(psp.taxjurcode, 44);
		struct.setValue(psp.int_profile, 45);
		struct.setValue(psp.joint_venture, 46);
		struct.setValue(psp.recovery_ind, 47);
		struct.setValue(psp.equity_type, 48);
		struct.setValue(psp.jv_object_type, 49);
		struct.setValue(psp.jv_jib_class, 50);
		struct.setValue(psp.jv_jib_sub_class_a, 51);
		struct.setValue(psp.objectclass_ext, 52);
		struct.setValue(psp.wbs_planning_element, 53);
		struct.setValue(psp.wbs_account_assignment_element, 54);
		struct.setValue(psp.wbs_billing_element, 55);
		struct.setValue(psp.respsbl_cctr, 56);
		struct.setValue(psp.respsbl_cctr_controlling_area, 57);
		struct.setValue(psp.request_cctr, 58);
		struct.setValue(psp.request_comp_code, 59);
		struct.setValue(psp.request_cctr_controlling_area, 60);
		struct.setValue(psp.location, 61);
		struct.setValue(psp.change_no, 62);
		struct.setValue(psp.invest_profile, 63);
		struct.setValue(psp.res_anal_key, 64);
		struct.setValue(psp.wbs_cctr_posted_actual, 65);
		struct.setValue(psp.wbs_basic_start_date, 66);
		struct.setValue(psp.wbs_basic_finish_date, 67);
		struct.setValue(psp.wbs_forecast_start_date, 68);
		struct.setValue(psp.wbs_forecast_finish_date, 69);
		struct.setValue(psp.wbs_actual_start_date, 70);
		struct.setValue(psp.wbs_actual_finish_date, 71);
		struct.setValue(psp.wbs_basic_duration, 72);
		struct.setValue(psp.wbs_basic_dur_unit, 73);
		struct.setValue(psp.wbs_basic_dur_unit_iso, 74);
		struct.setValue(psp.wbs_forecast_duration, 75);
		struct.setValue(psp.wbs_forcast_dur_unit, 76);
		struct.setValue(psp.wbs_forecast_dur_unit_iso, 77);
		struct.setValue(psp.wbs_actual_duration, 78);
		struct.setValue(psp.wbs_actual_dur_unit, 79);
		struct.setValue(psp.wbs_actual_dur_unit_iso, 80);
		struct.setValue(psp.func_area, 81);
		struct.setValue(psp.func_area_long, 82);
		/*struct.setValue(psp.wbs_element, "WBS_ELEMENT");
		struct.setValue(psp.project_definition, "PROJECT_DEFINITION");
		struct.setValue(psp.description, "DESCRIPTION");
		struct.setValue(psp.short_id, "SHORT_ID");
		struct.setValue(psp.responsible_no, "RESPONSIBLE_NO");
		struct.setValue(psp.applicant_no, "APPLICANT_NO");
		struct.setValue(psp.comp_code, "COMP_CODE");
		struct.setValue(psp.bus_area, "BUS_AREA");
		struct.setValue(psp.co_area, "CO_AREA");
		struct.setValue(psp.profit_ctr, "PROFIT_CTR");
		struct.setValue(psp.proj_type, "PROJ_TYPE");
		struct.setValue(psp.network_assignment, "NETWORK_ASSIGNMENT");
		struct.setValue(psp.costing_sheet, "COSTING_SHEET");
		struct.setValue(psp.overhead_key, "OVERHEAD_KEY");
		struct.setValue(psp.calendar, "CALENDAR");
		struct.setValue(psp.priority, "PRIORITY");
		struct.setValue(psp.equipment, "EQUIPMENT");
		struct.setValue(psp.functional_location, "FUNCTIONAL_LOCATION");
		struct.setValue(psp.currency, "CURRENCY");
		struct.setValue(psp.currency_iso, "CURRENCY_ISO");
		struct.setValue(psp.plant, "PLANT");
		struct.setValue(psp.user_field_key, "USER_FIELD_KEY");
		struct.setValue(psp.user_field_char20_1, "USER_FIELD_CHAR20_1");
		struct.setValue(psp.user_field_char20_2, "USER_FIELD_CHAR20_2");
		struct.setValue(psp.user_field_char10_1, "USER_FIELD_CHAR10_1");
		struct.setValue(psp.user_field_char10_2, "USER_FIELD_CHAR10_2");
		struct.setValue(psp.user_field_quan1, "USER_FIELD_QUAN1");
		struct.setValue(psp.user_field_unit1, "USER_FIELD_UNIT1");
		struct.setValue(psp.user_field_unit1_iso, "USER_FIELD_UNIT1_ISO");
		struct.setValue(psp.user_field_quan2, "USER_FIELD_QUAN2");
		struct.setValue(psp.user_field_unit2, "USER_FIELD_UNIT2");
		struct.setValue(psp.user_field_unit2_iso, "USER_FIELD_UNIT2_ISO");
		struct.setValue(psp.user_field_curr1, "USER_FIELD_CURR1");
		struct.setValue(psp.user_field_cuky1, "USER_FIELD_CUKY1");
		struct.setValue(psp.user_field_cuky1_iso, "USER_FIELD_CUKY1_ISO");
		struct.setValue(psp.user_field_curr2, "USER_FIELD_CURR2");
		struct.setValue(psp.user_field_cuky2, "USER_FIELD_CUKY2");
		struct.setValue(psp.user_field_cuky2_iso, "USER_FIELD_CUKY2_ISO");
		struct.setValue(psp.user_field_date1, "USER_FIELD_DATE1");
		struct.setValue(psp.user_field_date2, "USER_FIELD_DATE2");
		struct.setValue(psp.user_field_flag1, "USER_FIELD_FLAG1");
		struct.setValue(psp.user_field_flag2, "USER_FIELD_FLAG2");
		struct.setValue(psp.objectclass, "OBJECTCLASS");
		struct.setValue(psp.statistical, "STATISTICAL");
		struct.setValue(psp.taxjurcode, "TAXJURCODE");
		struct.setValue(psp.int_profile, "INT_PROFILE");
		struct.setValue(psp.joint_venture, "JOINT_VENTURE");
		struct.setValue(psp.recovery_ind, "RECOVERY_IND");
		struct.setValue(psp.equity_type, "EQUITY_TYPE");
		struct.setValue(psp.jv_object_type, "JV_OBJECT_TYPE");
		struct.setValue(psp.jv_jib_class, "JV_JIB_CLASS");
		struct.setValue(psp.jv_jib_sub_class_a, "JV_JIB_SUB_CLASS_A");
		struct.setValue(psp.objectclass_ext, "OBJECTCLASS_EXT");
		struct.setValue(psp.wbs_planning_element, "WBS_PLANNING_ELEMENT");
		struct.setValue(psp.wbs_account_assignment_element, "WBS_ACCOUNT_ASSIGNMENT_ELEMENT");
		struct.setValue(psp.wbs_billing_element, "WBS_BILLING_ELEMENT");
		struct.setValue(psp.respsbl_cctr, "RESPSBL_CCTR");
		struct.setValue(psp.respsbl_cctr_controlling_area, "RESPSBL_CCTR_CONTROLLING_AREA");
		struct.setValue(psp.request_cctr, "REQUEST_CCTR");
		struct.setValue(psp.request_comp_code, "REQUEST_COMP_CODE");
		struct.setValue(psp.request_cctr_controlling_area, "REQUEST_CCTR_CONTROLLING_AREA");
		struct.setValue(psp.location, "LOCATION");
		struct.setValue(psp.change_no, "CHANGE_NO");
		struct.setValue(psp.invest_profile, "INVEST_PROFILE");
		struct.setValue(psp.res_anal_key, "RES_ANAL_KEY");
		struct.setValue(psp.wbs_cctr_posted_actual, "WBS_CCTR_POSTED_ACTUAL");
		struct.setValue(psp.wbs_basic_start_date, "WBS_BASIC_START_DATE");
		struct.setValue(psp.wbs_basic_finish_date, "WBS_BASIC_FINISH_DATE");
		struct.setValue(psp.wbs_forecast_start_date, "WBS_FORECAST_START_DATE");
		struct.setValue(psp.wbs_forecast_finish_date, "WBS_FORECAST_FINISH_DATE");
		struct.setValue(psp.wbs_actual_start_date, "WBS_ACTUAL_START_DATE");
		struct.setValue(psp.wbs_actual_finish_date, "WBS_ACTUAL_FINISH_DATE");
		struct.setValue(psp.wbs_basic_duration, "WBS_BASIC_DURATION");
		struct.setValue(psp.wbs_basic_dur_unit, "WBS_BASIC_DUR_UNIT");
		struct.setValue(psp.wbs_basic_dur_unit_iso, "WBS_BASIC_DUR_UNIT_ISO");
		struct.setValue(psp.wbs_forecast_duration, "WBS_FORECAST_DURATION");
		struct.setValue(psp.wbs_forcast_dur_unit, "WBS_FORCAST_DUR_UNIT");
		struct.setValue(psp.wbs_forecast_dur_unit_iso, "WBS_FORECAST_DUR_UNIT_ISO");
		struct.setValue(psp.wbs_actual_duration, "WBS_ACTUAL_DURATION");
		struct.setValue(psp.wbs_actual_dur_unit, "WBS_ACTUAL_DUR_UNIT");
		struct.setValue(psp.wbs_actual_dur_unit_iso, "WBS_ACTUAL_DUR_UNIT_ISO");
		struct.setValue(psp.func_area, "FUNC_AREA");
		struct.setValue(psp.func_area_long, "FUNC_AREA_LONG");*/

	}
}
